Skip to content

兼容 Firefox MV3 规格#1457

Open
cyfung1031 wants to merge 13 commits into
mainfrom
ffmv3/compatibility/001
Open

兼容 Firefox MV3 规格#1457
cyfung1031 wants to merge 13 commits into
mainfrom
ffmv3/compatibility/001

Conversation

@cyfung1031
Copy link
Copy Markdown
Collaborator

@cyfung1031 cyfung1031 commented May 23, 2026

WindowMessage Transport Test 0.1.0

  • 通过 (5/5)

GM_xmlhttpRequest Exhaustive Test Harness 1.3.0

  • 大部份通过 (134/138)
  • Redirect handling (finalUrl changes) [error]Redirect handling (finalUrl changes) [manual] 未通过

半沙盒环境测试 0.2.0

  • 通过 (30/30)

Inject-into content 环境测试 0.1.0

  • 通过 (11/11)

GM API 完整测试 (同步版本) 1.1.0

  • 总计: 29 | 通过: 28 | 失败: 1
  • GM_addElement - 创建元素 Error: 脚本内容应该执行,unsafeWindow.foo 应该是 'bar' - 期望 "bar", 实际 undefined

GM.* API 完整测试 (异步版本) 1.0.0

  • 通过 (29/29)

Early-start Test (page 环境) 0.1.0

  • 通过 (14/14)

Early-start Test (content 环境) 0.1.0

  • 通过 (14/14)

后台脚本

  • 未支持
  • Firefox MV3 未有 sandbox。无法执行 unsafe-eval

@cyfung1031 cyfung1031 marked this pull request as draft May 23, 2026 02:57
@cyfung1031 cyfung1031 marked this pull request as ready for review May 23, 2026 04:04
@cyfung1031
Copy link
Copy Markdown
Collaborator Author

cyfung1031 commented May 23, 2026

@CodFrm

以下问题下回分解
先合并吧

  • GM_xhr: 仅 Redirect handling (finalUrl changes) [error] 和 Redirect handling (finalUrl changes) [manual] 未通过
  • @inject-into content + CSP: GM_addElement - 创建元素 Error: 脚本内容应该执行,unsafeWindow.foo 应该是 'bar' - 期望 "bar", 实际 undefined

@cyfung1031 cyfung1031 force-pushed the ffmv3/compatibility/001 branch 3 times, most recently from 0c166a5 to da7f8f1 Compare May 23, 2026 04:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 目标是让 ScriptCat 在 Firefox 的 MV3 规格下可运行:在无 chrome.offscreen 的情况下用“事件页 + iframe sandbox”替代 offscreen document,并补齐后台 GM_xmlhttpRequest 的 requestId/redirect 关联能力,同时修复/适配部分 Firefox 行为差异(如 HEAD 响应 body 为空、content 环境对象跨隔离边界拷贝等)。

Changes:

  • Service Worker 启动流程按是否支持 chrome.offscreen.createDocument 分支:Chromium 继续用 offscreen document;Firefox 改为 EventPageOffscreenManager(DOM 能力来自事件页自身)。
  • GM_xmlhttpRequest 新增 mv3_utils:Chromium 走临时 header marker + DNR 清理;Firefox 走 webRequest.onBeforeRequest 捕获 requestId 并与 markerID 关联。
  • content 环境新增 localizeObject 以在 Firefox 隔离环境中 clone 传入对象;并更新 e2e / example userscript 的运行入口 query 参数。

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/service_worker.ts 按是否支持 offscreen API 分支初始化 offscreen 发送器/管理器
src/pkg/utils/xhr/fetch_xhr.ts 放宽 Firefox/Fetch 在 HEAD/opaqueredirect 下 body === null 的处理逻辑
src/pkg/utils/xhr/bg_gm_xhr.ts 通过 gmXhrRequestLinker.send() 发送请求并携带 markerID
src/app/service/service_worker/index.ts 将 sender 抽象为 IOffscreenSend,兼容不同 offscreen 实现
src/app/service/service_worker/gm_api/mv3_utils.ts 新增 GM XHR requestId 关联工具:Firefox(webRequest) / Chromium(header+DNR)
src/app/service/service_worker/gm_api/mv3_utils.test.ts 新增(但目前偏向 Chromium 分支)单测
src/app/service/service_worker/gm_api/gm_xhr.ts finalUrl 获取逻辑增加 markerID 缺失日志
src/app/service/service_worker/gm_api/gm_api.ts 接入 gmXhrRequestLinker,并用 initiator/origin 过滤仅处理 SC 自身后台请求
src/app/service/offscreen/index.ts OffscreenManager 重构为继承 BackgroundEnvManagerBase
src/app/service/offscreen/gm_api.ts 适配 BgGMXhr 新构造参数(strategy/markerID)
src/app/service/offscreen/event_page_manager.ts 新增 Firefox MV3 事件页 offscreen 管理器(iframe sandbox + 进程内 Message)
src/app/service/offscreen/base.ts 抽取 offscreen/event-page 共有初始化逻辑基类
src/app/service/content/script_executor.ts 在执行入口对 envInfo/scriptLoadInfo 做 Firefox 兼容的本地化拷贝
src/app/service/content/global.ts 新增 Firefox content 环境检测与 localizeObject
packages/message/window_message.ts ServiceWorkerMessageSend 实现改为 IOffscreenSend
packages/message/types.ts 新增 IOffscreenSend 接口(MessageSend + init)
example/tests/window_message_test.js 新增 WindowMessage 传输链路回归脚本
example/tests/inject_content_test.js 更新 match 参数,便于通过 query 触发测试
example/tests/gm_xhr_test.js 更新版本并增强错误输出/Firefox 差异处理
example/tests/gm_xhr_redirect_test.js 新增 redirect/finalUrl 专项测试脚本
example/tests/gm_api_sync_test.js 重命名并通过 query 区分同步版本测试入口
example/tests/gm_api_async_test.js 通过 query 区分异步版本测试入口
example/tests/early_inject_page_test.js 通过 query 区分 early-start(page) 测试入口
example/tests/early_inject_content_test.js 通过 query 区分 early-start(content) 测试入口
e2e/gm-api.spec.ts e2e 跟随 example 脚本改名与 query 入口调整

Comment on lines +55 to +57
export const localizeObject = isFFContent
? <T = object>(script: T): T => customClone(script)
: <T = object>(script: T): T => script;
Copy link
Copy Markdown
Collaborator Author

@cyfung1031 cyfung1031 May 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里不预期出错 (structuredClone)
出错了也无法有效执行下去

Comment thread src/pkg/utils/xhr/fetch_xhr.ts
Comment on lines +84 to +93
const resolver = (o: TbgMarkerMapEntry) => {
const resolvePromise = o.resolvePromise;
const result = o.r;
bgMarkerMap.delete(o.url);
bgMarkerMap.delete(o.markerID);
scXhrRequests.set(o.reqId!, o.markerID);
scXhrRequests.set(o.markerID, o.reqId!);
o.r = null;
resolvePromise(result);
};
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

故意的代码设计。正确不用改

Comment on lines +133 to +155
async send(
baseXHR: FetchXHR | XMLHttpRequest,
data: XMLHttpRequestBodyInit | null | undefined,
{ markerID, url }: SendContext
) {
// Send data (if any)
if (!markerID) return baseXHR.send(data);
const fn = (resolve: any, _reject: any) => {
const wURL = normalizeBackgroundRequestUrl(url);
const o: TbgMarkerMapEntry = {
url: wURL,
markerID,
resolvePromise: resolve,
};
bgMarkerMap.delete(markerID);
bgMarkerMap.delete(wURL);
bgMarkerMap.set(markerID, o);
bgMarkerMap.set(wURL, o);
// Send data (if any)
o.r = baseXHR.send(data);
};
return await stackAsyncTask("bg_gm_xhr_queue", () => new Promise(fn));
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

此为正确设计

不用兜底

  1. 不使用 timer 兜底
  2. 一定要匹配 webRequest。实际情况下不会有「事件没来」。Promise必然 resolve

Comment thread src/app/service/service_worker/gm_api/mv3_utils.test.ts
@cyfung1031 cyfung1031 marked this pull request as draft May 23, 2026 06:05
@cyfung1031 cyfung1031 marked this pull request as ready for review May 23, 2026 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants